// 储存三种状态
const PENDING = 'PENDING' // 准备状态
const FULFILLED = 'FULLFILLED' //成功
const REJECTED = 'REJECTED' //失败

class myPromise {
  // 给Promise一个属性储存状态
  status = PENDING
  // 储存值和失败原因
  value = undefined
  reason = undefined
  // 储存成功和失败的回调
  onResolvedCallBacks = []
  onRejectedCallBacks = []
  // constructor等于构造函数本身 extutor接收new实例时传入的参数(函数)
  constructor(excutor) {
    // 定义成功函数
    let resolve = (value) => {
      // 成功和失败的状态都只能从等待状态变化而来
      if (this.status === PENDING) {
        this.value = value; // 赋值
        this.status = FULFILLED; // 改变为成功状态
        // 调用之前存储的成功的回调——发布
        this.onResolvedCallBacks.forEach(fn=>fn())
      }
    }
    // 定义失败函数
    let reject = (reason) => {
      if (this.status === PENDING) { 
        this.reason = reason; // 拿到原因
        this.status = REJECTED; // 改变为失败状态
        // 调用存储的失败的回调——发布
        this.onRejectedCallBacks.forEach(fn=>fn())
      }
    }
    //执行实例化时传入的函数excutor，并将成功、失败函数作为参数
    // 捕获excutor执行时的错误调用reject作为失败错误
    try {
      excutor(resolve, reject) 
    } catch (error) {
      reject(error)
    }
  }

  // 定义then方法,参数为成功的回调、失败的回调
  then(onFulfilled, onRejected) {
    // 成功状态的回调
    if (this.status === FULFILLED) {
      setTimeout(() => {
        onFulfilled(this.value) // 传入值
      },0)
    }
    // 失败状态的回调
    if (this.status === REJECTED) {
      setTimeout(() => {
        onRejected(this.reason) // 传入失败原因
      },0)
    }
    // 处理异步任务时，状态未改变仍为PENDING
    if (this.status===PENDING) {
      // 存储成功、失败的回调——订阅
      // 用箭头函数包裹回调，不立即执行，在resolve、reject时再遍历执行
      this.onResolvedCallBacks.push(() => {
        onFulfilled(this.value)
      })
      this.onRejectedCallBacks.push(() => {
        onRejected(this.reason)
      })
    }
  }
}
